﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Data;
using System.Data.SqlClient;
using System.Configuration;
using System.Runtime;
using System.Runtime.Remoting;
using System.Runtime.Remoting.Channels;
using System.Runtime.Remoting.Channels.Tcp;
using System.IO;
using System.IO.Compression;
using System.Collections;
using System.Net.NetworkInformation;
using System.Net;
using Pub.Tools;

namespace Pub.Lib
{
    public static class Remoting
    {

        public static void TryFirstConnet()
        {

            try
            {
                string strConn = Helper.DBHelper.GetConnstring(); //测试与Remoting服务器连接
            }
            catch (Exception ex)
            {

           //     PubTools.MsgClass.ErrorMsg(ex.Message.ToString());
                System.Environment.Exit(System.Environment.ExitCode);
            }


        }

        /// <summary>
        /// 选择加载服务类型
        /// </summary>
        public static void LoadRemoting()
        {
            if (PubVar.SysSecure_Username != string.Empty)
            {
                PubVar.SysDATName = "认证 Remoting";
                LoadSecure();
            }
            else
            {
                PubVar.SysDATName = "Remoting";
                PTLoad();
            }

        }


        /// <summary>
        /// 取消加载服务类型
        /// </summary>
        public static void UnLoadRemoting()
        {
            if (PubVar.SysSecure_Username != string.Empty)
            {
                UnLoadSecure();
            }
            else
            {
              //  PTLoad();
            }

        }


        /// <summary>
        /// 初始化认证通道注册
        /// </summary>
        public static void LoadSecure()
        {
            if (FindChannel("MyTcpClient"))
            {
                return;
            }

            //System.Windows.Forms.Cursor.Current = System.Windows.Forms.Cursors.WaitCursor;


            try
            {
                string strPath = XmlTools.GetRandomServiceURL(PubVar.SysServerUrlList); //获取服务器端口

                strPath = strPath.Replace( "http://","tcp://");

                PubVar.SysServerURL = strPath;

                IDictionary myDic = new Hashtable();
                myDic["name"] = "MyTcpClient";
                myDic["port"] = 0;
                myDic["impersonationLevel"] = "Identify";
                myDic["tokenImpersonationLevel"] = "Identification";

                myDic["secure"] = true; //进行加密标识，上面两个标识是加密所必须的。进行证书交换

                if (PubVar.SysSecure_Domain != string.Empty)
                {
                    myDic["domain"] = PubVar.SysSecure_Domain; 
                }

                if (PubVar.SysSecure_Username != string.Empty)
                {
                    myDic["username"] = PubVar.SysSecure_Username; // 在不以域组的网络上，如果不加用户名与密码时，会出现认证不过的情况
                }

                if (PubVar.SysSecure_Password != string.Empty)
                {
                    myDic["password"] = PubVar.SysSecure_Password; // 在不以域组的网络上，如果不加用户名与密码时，会出现认证不过的情况
                }  
  


                //myDic["username"] = "test"; // 在不以域组的网络上，如果不加用户名与密码时，会出现认证不过的情况
                //myDic["password"] = "test";

                BinaryServerFormatterSinkProvider bsp = new BinaryServerFormatterSinkProvider();
                bsp.TypeFilterLevel = System.Runtime.Serialization.Formatters.TypeFilterLevel.Full;

                BinaryClientFormatterSinkProvider bcp = new BinaryClientFormatterSinkProvider();

                //     TcpChannel channle = new TcpChannel(myDic, bcp, bsp);


                PubVar.MyChannle = new TcpChannel(myDic, bcp, bsp);



                string aa = ChannelServices.RegisteredChannels.Length.ToString();


                ChannelServices.RegisterChannel(PubVar.MyChannle, false);



                PubVar.objdb = (DBAccess)Activator.GetObject(typeof(DBAccess), strPath + PubVar.strDBAccess);
                PubVar.objsysUser = (SysUser)Activator.GetObject(typeof(SysUser), strPath + PubVar.strSysUser);

                //strConn = 
             //   DateTime datetime = PubVar.objdb.GetServerTime(PubVar.ConnMain);


            }
            catch (Exception ex)
            {
                throw ex;
            }

        }


        /// <summary>
        /// 查找是否已经创建Channel
        /// </summary>
        /// <param name="_ChannelName"></param>
        /// <returns></returns>
        public static Boolean FindChannel(string _ChannelName)
        {
            Boolean bl = false;
            for (int ii = 0; ii < ChannelServices.RegisteredChannels.Length; ii++)
            {
                //if              
                if (ChannelServices.RegisteredChannels[ii].ChannelName.ToString() == _ChannelName)
                {
                    bl = true;
                    break;
                }
            }
            return bl;

        }

        /// <summary>
        /// 取消认证通道注册
        /// </summary>
        public static void UnLoadSecure()
        {
            try
            {
                if (PubVar.MyChannle.ChannelData != null)
                {
                    ChannelServices.UnregisterChannel(PubVar.MyChannle);
                }
            }
            catch (Exception ex)
            {
 //               System.Windows.Forms.Cursor.Current = System.Windows.Forms.Cursors.Default;
                throw ex;
            }
        }

        /// <summary>
        /// 普通通道加载
        /// </summary>
        private static void PTLoad() //普通加载
        {
            try
            {

                //获取服务器端口
                string strPath = XmlTools.GetRandomServiceURL(PubVar.SysServerUrlList); 


                strPath = strPath.Replace("http://", "tcp://");

                PubVar.SysServerURL = strPath;

                TcpClientChannel channle = new TcpClientChannel();

                PubVar.objdb = (DBAccess)Activator.GetObject(typeof(DBAccess), strPath + PubVar.strDBAccess);
                PubVar.objsysUser = (SysUser)Activator.GetObject(typeof(SysUser), strPath + PubVar.strSysUser);

               // DateTime datetime = PubVar.objdb.GetServerTime(PubVar.ConnMain);
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }
    }

    public static class RemotingServer
    {
        public static string Start(ref TcpServerChannel tcpServerChannel, string strPort)
        {
            string strMess = string.Empty;
            try
            {
                tcpServerChannel = new TcpServerChannel(SysTools.ToInt(strPort));

                ChannelServices.RegisterChannel(tcpServerChannel, false);
                if (tcpServerChannel != null)
                {
                    RemotingConfiguration.RegisterWellKnownServiceType(typeof(DBAccess), PubVar.strDBAccess, WellKnownObjectMode.Singleton);
                    RemotingConfiguration.RegisterWellKnownServiceType(typeof(SysUser), PubVar.strSysUser, WellKnownObjectMode.Singleton);
                    strMess = "Remoting 端口" + strPort + "(普通模式)服务启动成功";
                }
                else
                {
                    strMess = "Remoting 端口" + strPort + "(普通模式)服务启动失败";
                }
            }
            catch (Exception ex)
            {
                strMess = "Remoting 端口" + strPort + "(普通模式)服务启动失败\r\n" + ex.Message.ToString(); ;
            }
            return strMess;
        }
        public static string SecureStart(ref TcpChannel tcpChannel, string strPort)
        {
            string strMess = string.Empty;

            try
            {

                IDictionary myDic = new Hashtable();
                myDic["port"] = SysTools.ToInt(strPort);
                myDic["name"] = "MyTcpServer";
                myDic["authenticationMode"] = "identifyCallers";
                myDic["tokenImpersonationLevel"] = "Identification";
                myDic["secure"] = true;

                BinaryServerFormatterSinkProvider bsp = new BinaryServerFormatterSinkProvider();
                bsp.TypeFilterLevel = System.Runtime.Serialization.Formatters.TypeFilterLevel.Full;

                BinaryClientFormatterSinkProvider bcp = new BinaryClientFormatterSinkProvider();

                tcpChannel = new TcpChannel(myDic, bcp, bsp);


                ChannelServices.RegisterChannel(tcpChannel, false);
                if (tcpChannel != null)
                {
                    RemotingConfiguration.RegisterWellKnownServiceType(typeof(DBAccess), PubVar.strDBAccess, WellKnownObjectMode.Singleton);
                    RemotingConfiguration.RegisterWellKnownServiceType(typeof(SysUser), PubVar.strSysUser, WellKnownObjectMode.Singleton);
                    strMess = "Remoting 端口" + strPort + "(用户认证模式)服务启动成功";
                }
                else
                {
                    strMess = "Remoting 端口" + strPort + "(用户认证模式)服务启动失败";
                }

            }
            catch (Exception ex)
            {
                strMess = "Remoting 端口" + strPort + "(用户认证模式)服务启动失败\r\n" + ex.Message.ToString();
            }
            return strMess;
        }
    }

}
